package com.es.map;

/**
 * @author 二十
 * @since 2022/1/17 9:35 下午
 */
public class LinkedListMap<K, V> extends AbstractMap<K, V> {

    private class Node {
        K key;
        V value;
        Node next;

        public Node(K key, V value, Node node) {
            this.key = key;
            this.value = value;
            this.next = node;
        }

        public Node(K key, Node node) {
            this(key, null, node);
        }

        public Node(Node node) {
            this(null, null, node);
        }

        @Override
        public String toString() {
            return "key:" + key + " value: " + value;
        }
    }

    private Node head = new Node(null);

    private int size;

    @Override
    public void add(K k, V v) {
        head.next = new Node(k, v, head.next);
        size++;
    }

    @Override
    public V remove(K k) {
        Node p = head;
        while (p.next != null) {
            if (p.next.key.equals(k)) {
                V ret = p.next.value;
                p.next = p.next.next;
                size--;
                return ret;
            }
            p = p.next;
        }
        return null;
    }

    @Override
    public boolean contains(K k) {
        Node p = head;
        while (p.next != null) {
            if (p.next.key.equals(k)) {
                return true;
            }
            p = p.next;
        }
        return false;
    }

    @Override
    public V get(K k) {
        Node p = head;
        while (p.next != null) {
            if (p.next.key.equals(k)) {
                return p.next.value;
            }
            p = p.next;
        }
        return null;
    }

    @Override
    public void set(K k, V v) {
        Node p = head;
        boolean flag = false;
        while (p.next != null) {
            if (p.next.key.equals(k)) {
                p.next.value = v;
                flag = true;
            }
            p = p.next;
        }
        if (!flag) {
            add(k, v);
        }
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("Map:[ ");
        Node p = head.next;
        for (int i = 0; i < size; i++) {
            sb.append(p.key).append(" : ").append(p.value);
            if (i != size - 1) {
                sb.append(",");
            }
            p = p.next;
        }
        return sb.append(" ]").toString();
    }
}
